package com.qf.agro.Interceptceptor;

import com.alibaba.fastjson.JSON;
import com.qf.agro.common.Constant;
import com.qf.agro.common.ResultInfo;
import com.qf.agro.common.SysUserHolder;
import com.qf.agro.pojo.SysUser;
import com.qf.agro.util.JwtUtil;
import io.jsonwebtoken.Claims;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author 10202
 * @version V1.0
 * @Project smart-agriculture-parent
 * @Package com.qf.agro.Interceptceptor
 * @Date 2023/5/22 12:12
 */
@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // // 放行预请求
        // if("OPTIONS".equals(request.getMethod())){
        //     return true;
        // }

        // 从前端的到请求头当中获取token.
        String token = request.getHeader("Authorization");
        // 表示未登录.
        if(token == null){
            ResultInfo resultInfo = ResultInfo.error(Constant.NOT_LOGIN);
            response.getWriter().write(JSON.toJSONString(resultInfo));
            return false;
        }

        // 如果token存在。则处理流程如下：
        // 解析一下token.拿出咱们存储在token当中的subject. -----> SysUser对象.
        // 解析过程当中,如果token过期了.这个流程是这样的:
        //      正常的套路解析.但是解析完成之后,它会抛出一个异常
        //      ExpiredJwtException
        // 判断一下当前的token是否已经过期了.
        if ("null".equals(token)||JwtUtil.tokenlsExpired(token)) { // 如果token已经过期了.则强制用户进行登录.
            ResultInfo resultInfo = ResultInfo.error(Constant.NOT_LOGIN);
            response.getWriter().write(JSON.toJSONString(resultInfo));
            return false;
        }


        // 正经的解析token
        Claims claims = JwtUtil.parseJWT(token);
        String sysUserId = claims.getId();
        String subject = claims.getSubject(); // 之前token当中存储的是SysUser对象的json字符串.
        SysUser sysUser = JSON.parseObject(subject, SysUser.class);
        SysUserHolder.set(sysUser);//  将当前的对象绑定线程当中.

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        SysUserHolder.remove();
    }
}
